// prints the links in an HTML document read from standard input.
package main

import (
	"fmt"
	"os"

	"golang.org/x/net/html" // 未将这些扩展包加入到标准库原因有二，一是部分 包仍在开发中，二是对大多数Go语言的开发者而言，扩展包提供的功能很少被使用。
)

// appends to links each link found in n and returns the result.
func visit(links []string, n *html.Node) []string {
	if n.Type == html.ElementNode && (n.Data == "a" || n.Data == "script" || n.Data == "link" || n.Data == "img") {
		for _, a := range n.Attr {
			if a.Key == "href" || a.Key == "src" {
				links = append(links, a.Val)
			}
		}
	}
	if n.FirstChild != nil {
		links = visit(links, n.FirstChild)
	}
	if n.NextSibling != nil {
		links = visit(links, n.NextSibling)
	}
	return links
}

// 练习 5.2: 编写函数，记录在HTML树中出现的同名元素的次数。
func times(map1 map[string]int, n *html.Node) map[string]int {
	if n.Type == html.ElementNode && n.Data != "" {
		map1[n.Data]++
	}
	if n.FirstChild != nil {
		times(map1, n.FirstChild)
	}
	if n.NextSibling != nil {
		times(map1, n.NextSibling)
	}
	return map1
}

// 练习 5.3: 编写函数输出所有text结点的内容。注意不要访问 <script> 和 <style> 元素,因为这些元素对浏览者是不可见的。
func text(n *html.Node) {
	if n.Type == html.TextNode && n.Data != "" && n.Parent.Data != "script" && n.Parent.Data != "style" {
		fmt.Println(n.Data)
	}
	if n.FirstChild != nil {
		text(n.FirstChild)
	}
	if n.NextSibling != nil {
		text(n.NextSibling)
	}

}
func main() {
	doc, err := html.Parse(os.Stdin)
	if err != nil {
		fmt.Fprintf(os.Stderr, "findlinks1: %v\n", err)
		os.Exit(1)
	}
	for _, link := range visit(nil, doc) {
		fmt.Println(link)
	}
	map1 := make(map[string]int)
	map1 = times(map1, doc)

	fmt.Println(map1)

	text(doc)

}
